package com.fypg.module.blooddonation.api.client.utils;

import com.fypg.module.blooddonation.api.client.config.BloodStationConfig;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.springframework.stereotype.Component;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.Base64;

@Component
public class Sm4KeyUtil {
    static {
        // 添加安全提供者（SM2，SM3，SM4等加密算法，CBC、CFB等加密模式，PKCS7Padding等填充方式）
        Security.addProvider(new BouncyCastleProvider());
    }

    // 静态密钥变量
    private static String SM4_KEY_BYTES;

    private final BloodStationConfig bloodStationConfig;

    public Sm4KeyUtil(BloodStationConfig bloodStationConfig) {
        this.bloodStationConfig = bloodStationConfig;
        SM4_KEY_BYTES = bloodStationConfig.getSm4Key();
    }

    /**----------------- 加密 -----------------**/

    public static String sm4Encrypt(String plainString, String key) {
        return sm4Encrypt(plainString, getDecodedKey(key));
    }

    public static String sm4Encrypt(String plainString) {
        return sm4Encrypt(plainString, getDecodedKey(SM4_KEY_BYTES));
    }

    private static String sm4Encrypt(String plainString, byte[] keyBytes) {
        try {
            String algorithm = "SM4";
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, algorithm);
            Cipher cipher = Cipher.getInstance(algorithm + "/ECB/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);

            byte[] cipherBytes = cipher.doFinal(plainString.getBytes(StandardCharsets.UTF_8));

            // 使用 URL 安全 Base64，去掉填充
            return Base64.getUrlEncoder().withoutPadding().encodeToString(cipherBytes);

        } catch (Exception e) {
            throw new RuntimeException("SM4加密失败: " + e.getMessage(), e);
        }
    }

    /**----------------- 解密 -----------------**/

    public static String sm4Decrypt(String cipherString, String key) {
        return sm4Decrypt(getDecodedCipher(cipherString), getDecodedKey(key));
    }

    public static String sm4Decrypt(String cipherString) {
        return sm4Decrypt(getDecodedCipher(cipherString), getDecodedKey(SM4_KEY_BYTES));
    }

    public static String sm4Decrypt(byte[] cipherBytes, byte[] keyBytes) {
        String plainString = null;
        try {
            String algorithm = "SM4";
            SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, algorithm);
            Cipher cipher = Cipher.getInstance(algorithm + "/ECB/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);

            byte[] plainBytes = cipher.doFinal(cipherBytes);
            plainString = new String(plainBytes, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return plainString;
    }

    /**----------------- 工具方法 -----------------**/

    /**
     * 将平台 Base64 字符串解码（URL-safe Base64）
     */
    private static byte[] getDecodedCipher(String base64String) {
        if (base64String == null) {
            throw new IllegalArgumentException("Base64字符串不能为空");
        }
        return Base64.getUrlDecoder().decode(base64String);
    }

    /**
     * 将 key Base64 字符串解码（URL-safe Base64）
     */
    private static byte[] getDecodedKey(String base64Key) {
        if (base64Key == null) {
            throw new IllegalArgumentException("密钥不能为空");
        }
        return Base64.getUrlDecoder().decode(base64Key);
    }

    /**----------------- 获取密钥 -----------------**/
    public String getSm4Key() {
        return SM4_KEY_BYTES;
    }
}
